package qualomelhor.game;

import pythagoras.f.Path;
import pythagoras.f.*;
import static playn.core.PlayN.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

import org.jbox2d.callbacks.DebugDraw;
import org.jbox2d.collision.shapes.CircleShape;
import org.jbox2d.collision.shapes.PolygonShape;
import org.jbox2d.common.MathUtils;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.BodyDef;
import org.jbox2d.dynamics.BodyType;
import org.jbox2d.dynamics.FixtureDef;
import org.jbox2d.dynamics.World;
import org.jbox2d.dynamics.joints.ConstantVolumeJointDef;
import org.jbox2d.dynamics.joints.DistanceJointDef;
import org.jbox2d.dynamics.joints.RevoluteJointDef;
import org.jbox2d.dynamics.joints.Joint;

import com.google.gwt.user.client.Timer;
import playn.core.*;
import pythagoras.f.PathIterator;

public class TesteGame implements Game {

	private CanvasImage canvasImgDraw;
	private GroupLayer lyDraw;
	private Body body;
	private int numMsg = 0;
	private GroupLayer peaLayer;
	private List<Pea> peas = new ArrayList<Pea>(0);
	private GroupLayer worldLayer;
	private MyWorld myWorld;
	private RevoluteJointDef jd;
	//public static float physUnitPerScreenUnit = 1 / 26.666667f;
	public static float physUnitPerScreenUnit = 1 / 13.333334f;
	//public static float physUnitPerScreenUnit = 1 / 6.666667f;
	//public static float physUnitPerScreenUnit = 1 / 8;
	//public static float physUnitPerScreenUnit = 1 / 4;
	//public static float physUnitPerScreenUnit = 1 / 1;
	private ConstantVolumeJointDef cvjd;
	private int group1 = -1;
	private int group2 = -2;
	
	final int k_triangleCategory = 0x0002;
	final int k_circleCategory = 0x0008;
	final int k_defaultCategory = 0x0001;
	final int k_boxCategory = 0x0004;
	
	final int k_triangleMask = 0xFFFF;
	final int k_boxMask = 0xFFFF ^ k_triangleCategory;
	final int k_circleMask = 0xFFFF;
	final int k_testeMask = 0xFFFF ^ k_circleCategory;

	private int numClicks = 0;

	public static native void alert(String msg) /*-{
		$wnd.alert(msg);
	}-*/;

	public static native void setMessageBox(String msg) /*-{
		//$wnd.alert("alerting..." + msg);
		$wnd.messageBox(msg);
	}-*/;

	@Override
	public void init() {
		PlayN.graphics().setSize(600, 300);
	}

	public TesteGame() {
		System.out.println("Iniciando game...");
		setMessageBox("Iniciando game...");

	    lyDraw = graphics().createGroupLayer();
	    graphics().rootLayer().add(lyDraw);

	    worldLayer = graphics().createGroupLayer();
	    worldLayer.setScale(1f / physUnitPerScreenUnit);
	    graphics().rootLayer().add(worldLayer);

	    myWorld = new MyWorld(worldLayer, physUnitPerScreenUnit);
	    cvjd = new ConstantVolumeJointDef();

	    peaLayer = graphics().createGroupLayer();
	    graphics().rootLayer().add(peaLayer);

	    // preload the pea image into the asset manager cache
	    assets().getImage(Pea.IMAGE);

		// cria o teto
	    BodyDef fixBd = new BodyDef();
		final Body ground = myWorld.world.createBody(fixBd);
		PolygonShape groundShape = new PolygonShape();
		groundShape.setAsEdge(new Vec2(5.0f * physUnitPerScreenUnit, 5.0f * physUnitPerScreenUnit), new Vec2(595.0f * physUnitPerScreenUnit, 50.0f * physUnitPerScreenUnit));
		ground.createFixture(groundShape, 0.0f);
	    
		jd = new RevoluteJointDef();
		jd.collideConnected = false;
		
		
	    /*
	    Path p = new Path(Path.WIND_EVEN_ODD);
	    p.moveTo(10, 10);
	    p.lineTo(500, 200);
	    PathIterator pI = p.pathIterator(null);
	    float[] cord = new float[100];
	    int r = pI.currentSegment(cord);
	    System.out.println("r = " + r);
	    for (int i = 0; i < cord.length; i++) {
	    	System.out.println("cord[" + i + "] = " + cord[i]);	
	    }
	    pI.next();

	    r = pI.currentSegment(cord);
	    System.out.println("r = " + r);
	    for (int i = 0; i < cord.length; i++) {
	    	System.out.println("cord[" + i + "] = " + cord[i]);	
	    }
	    */
	    
	    
	    PlayN.pointer().setListener(new Pointer.Adapter() {
	    	
	    	@Override
	    	public void onPointerDrag(Pointer.Event event) {

	    		//int x = (int)event.x();
	    		//int y = (int)event.y();

	    	}

	    	@Override
	    	public void onPointerEnd(Pointer.Event event) {
	    		setMessageBox("numClicks = " + numClicks);
	    		Body ground = null;
	    		{
	    			BodyDef bd = new BodyDef();
	    			ground = myWorld.world.createBody(bd);

	    			PolygonShape shape = new PolygonShape();
	    			shape.setAsEdge(new Vec2(50.0f * physUnitPerScreenUnit, 5.0f), new Vec2(500.0f * physUnitPerScreenUnit, 5.0f));
	    			ground.createFixture(shape, 0.0f);
	    		}

	    		
	    	    BodyDef bdJuncD = new BodyDef();
	    	    bdJuncD.fixedRotation = true;
	    	    bdJuncD.position.set(new Vec2(340 * physUnitPerScreenUnit, 130 * physUnitPerScreenUnit));
	    	    bdJuncD.type = BodyType.STATIC;
	    		Body juncBracoD = myWorld.world.createBody(bdJuncD);
	    		CircleShape juncShapeD = new CircleShape();
	    		juncShapeD.m_radius = 2f;
    			FixtureDef fdD = new FixtureDef();
    			fdD.shape = juncShapeD;
    			fdD.density = 0.0f;
    			fdD.filter.groupIndex = -1;
    			fdD.filter.categoryBits = k_defaultCategory;
    			//fdD.filter.maskBits = k_boxMask;
	    		juncBracoD.createFixture(fdD);
	    		
	    		
	    	    BodyDef bdJuncE = new BodyDef();
	    	    //bdJuncE.fixedRotation = true;
	    	    bdJuncE.position.set(new Vec2(150 * physUnitPerScreenUnit, 130 * physUnitPerScreenUnit));
	    	    bdJuncE.type = BodyType.STATIC;
	    		Body juncBracoE = myWorld.world.createBody(bdJuncE);
	    		CircleShape juncShapeE = new CircleShape();
	    		juncShapeE.m_radius = 4f;
    			FixtureDef fdE = new FixtureDef();
    			fdE.shape = juncShapeE;
    			fdE.density = 0.0f;
    			fdE.filter.groupIndex = -1;
    			fdE.filter.categoryBits = k_circleCategory;
    			fdE.filter.maskBits = k_testeMask;
	    		juncBracoE.createFixture(fdE);
	    		
	    		{
	    			PolygonShape shape = new PolygonShape();
	    			shape.setAsBox(8f * physUnitPerScreenUnit, 8f * physUnitPerScreenUnit);

	    			RevoluteJointDef jd = new RevoluteJointDef();
	    			jd.collideConnected = false;

	    			final float y = 155.0f * physUnitPerScreenUnit;
	    			Body prevBody = juncBracoD;
	    			int i = 1;
	    			for (i = 1; i < 20; ++i)
	    			{
		    			FixtureDef fd = new FixtureDef();
		    			fd.shape = shape;
		    			fd.density = 20.0f;
		    			fd.friction = 0.2f;
		    			//fd.filter.groupIndex = -1;
		    			fd.filter.groupIndex = (numClicks == 0?1:0);
		    			fd.filter.categoryBits = (numClicks == 0?k_triangleCategory:k_boxCategory);
	    				fd.filter.maskBits = k_boxMask;
		    			//fd.filter.maskBits = k_testeMask;
		    			
	    				BodyDef bd = new BodyDef();
	    				bd.type = BodyType.DYNAMIC;
	    				bd.position.set((300f - i) * physUnitPerScreenUnit, y - i);
	    				Body body = myWorld.world.createBody(bd);
	    				body.createFixture(fd);

	    				Vec2 anchor = new Vec2((299 - i) * physUnitPerScreenUnit, y - i);
	    				jd.initialize(prevBody, body, anchor);
	    				myWorld.world.createJoint(jd);

	    				prevBody = body;
	    			}
	    			
    				Vec2 anchor = new Vec2((200 - i) * physUnitPerScreenUnit, y - i);
    				jd.initialize(prevBody, juncBracoE, anchor);
    				myWorld.world.createJoint(jd);
    			
	    			numClicks++;
	    		}
	    		
	    		/*
	    	    // cria a junçao fixa dos bracos
	    	    //****************************************
	    	    BodyDef bdJuncD = new BodyDef();
	    	    bdJuncD.fixedRotation = true;
	    	    bdJuncD.position.set(new Vec2(342 * physUnitPerScreenUnit, 100 * physUnitPerScreenUnit));
	    	    bdJuncD.type = BodyType.STATIC;
	    		Body juncBracoD = myWorld.world.createBody(bdJuncD);
	    		CircleShape juncShapeD = new CircleShape();
	    		juncShapeD.m_radius = 2f;
	    		juncBracoD.createFixture(juncShapeD, 0.0f);

	    	    BodyDef bdJuncE = new BodyDef();
	    	    bdJuncE.fixedRotation = true;
	    	    bdJuncE.position.set(new Vec2(150 * physUnitPerScreenUnit, 100 * physUnitPerScreenUnit));
	    	    bdJuncE.type = BodyType.STATIC;
	    		Body juncBracoE = myWorld.world.createBody(bdJuncE);
	    		CircleShape juncShapeE = new CircleShape();
	    		juncShapeE.m_radius = 2f;
	    		juncBracoE.createFixture(juncShapeE, 0.0f);
	    		//****************************************
	    		
	    		//Cria os joints dos bracos
	    		//****************************************
	    		setMessageBox("Adicionando joints...");
	    		float cx = physUnitPerScreenUnit * (342 + 30);
	    		float cy = physUnitPerScreenUnit * 100;
	    		float rx = cx + 5;
	    		float ry = cy + 5;
	    		int nBodies = 4;
	            
	            Body bodyPrev = juncBracoD;
	    		float y = cy;
	    		for (int i = 0; i < nBodies; ++i) {

	    			float x = cx;
	    			y += 3;

	    		    BodyDef bd = new BodyDef();
	    		    bd.fixedRotation = true;
	    		    bd.position.set(new Vec2(x, y));
	    		    bd.type = BodyType.DYNAMIC;
	    			Body body = myWorld.world.createBody(bd);
	    			CircleShape cShape = new CircleShape();
	    			cShape.m_radius = 1f;
	    			body.createFixture(cShape, 0.0f);

	    			setMessageBox("joints:..." + i);
    				ConstantVolumeJointDef cvjd = new ConstantVolumeJointDef();
    				cvjd.collideConnected = false;

	    			cvjd.addBody(bodyPrev);
    				cvjd.addBody(body);
    	    		cvjd.frequencyHz = 10.0f;
    	    		cvjd.dampingRatio = 1.0f;
    				myWorld.world.createJoint(cvjd);

    				bodyPrev = body;
    				setMessageBox("fim joints:..." + i);
	    		}
	    		

	    		setMessageBox("joints loop ok...x, y = (" + cx + "," + cy + ")");
	    		*/

	    		
	    		/*
	    		setMessageBox("Adicionando circle img...");
	    		CanvasImage cvI = criaImage(600, 300);
	    		cvI.canvas().fillCircle(event.x(), event.y(), 100);
	    		cvI.canvas().setFillColor(Color.rgb(999999, 999999, 999999));
	    		cvI.canvas().fillCircle(event.x(), event.y(), 100);
	    		ImageLayer img = graphics().createImageLayer(cvI);
	    		Image i = assets().getImage("/images/bg.png");
	    		ImageLayer im = graphics().createImageLayer(i);
	    		lyDraw.add(im);
	    		lyDraw.add(img);
	    		setMessageBox("img adicionada...");
	    		*/

	    		//************Pea test****************
	    		/*
	    		Pea p = new Pea(peaLayer, event.x(), event.y());
	    		peas.add(p);

	    		
	    		PeaPhy peaPhy = new PeaPhy(myWorld, myWorld.world, physUnitPerScreenUnit * event.x(), physUnitPerScreenUnit * event.y(), 0);
	    		myWorld.add(peaPhy);
	    		peaPhy.getBody().applyForce(new Vec2(600, 300), peaPhy.getBody().getPosition());
	    		*/
	    		//************************************

	    		
	    		/*
	    		final Image imgMao = assets().getImage("/images/avatar/mao/mao2.png");

	    		setMessageBox("Teste");
	    		final float x = physUnitPerScreenUnit * event.x();
	    		final float y = physUnitPerScreenUnit * event.y();

	    	    AssetWatcher as = new AssetWatcher(new AssetWatcher.Listener() {
	    			@Override
	    			public void error(Throwable e) {
	    				setMessageBox("Erro ao carregar as imagens...");
	    			}

	    			@Override
	    			public void done() {
	    				setMessageBox("carregou as imagens das maos...w,h = " + imgMao.width() + "," + imgMao.height());
	    				//setMessageBox("w,h (corrigidas) = " + (imgMao.width() / physUnitPerScreenUnit) + "," + (imgMao.height() / physUnitPerScreenUnit));

	    	    		PeaPhy peaPhy = new PeaPhy(myWorld, myWorld.world, x + 10, y + 10, 0);
	    	    		myWorld.add(peaPhy);
	    	    		peaPhy.getBody().applyForce(new Vec2(600, 300), peaPhy.getBody().getPosition());

	    	    		setMessageBox("vai criar as maos...w, h = (" + (imgMao.width() * physUnitPerScreenUnit) + ", " + (imgMao.height() * physUnitPerScreenUnit) + ")");
	    				Mao2 mao = new Mao2(myWorld, myWorld.world, x, y, (imgMao.width() * physUnitPerScreenUnit), (imgMao.height() * physUnitPerScreenUnit), 0, 1, 1, imgMao, physUnitPerScreenUnit);
	    				setMessageBox("vai adicionar ao mundo ...");
	    			    myWorld.add(mao);
	    			    
	    			    //mao.getBody().applyForce(new Vec2(600, 300), peaPhy.getBody().getPosition());
	    	    		
	    			    setMessageBox("criou a mao...");
	    			}
	    		});
	    		as.add(imgMao);
	    		as.start();
	    		
	    		*/
	    		
	    		
	    		
	    		
	    		
	    		
	    		
	    		
	    		//*************************************
	    		/*
	    		setMessageBox("Adicionando joints...");
	    		float cx = physUnitPerScreenUnit * event.x();
	    		float cy = physUnitPerScreenUnit * event.y();
	    		float rx = physUnitPerScreenUnit * 30.0f;
	    		float ry = physUnitPerScreenUnit * 30.0f;
	    		int nBodies = 6;
	    		float bodyRadius = 0.5f;
	    		ConstantVolumeJointDef cvjd = new ConstantVolumeJointDef();
	    		float xExt = 0, yExt = 0;
	    		for (int i=0; i<nBodies; ++i) {
	    			float angle = MathUtils.map(i, 0, nBodies, 0, 2*3.1415f);
	    			BodyDef bd = new BodyDef();
	    			//bd.isBullet = true;
	    			bd.fixedRotation = true;

	    			float x = cx + rx * (float)Math.sin(angle);
	    			float y = cy + ry * (float)Math.cos(angle);
	    			if (xExt == 0 || yExt == 0) {
	    				xExt = x;
	    				yExt = y;
	    			}
	    			bd.position.set(new Vec2(x,y));
	    			bd.type = BodyType.DYNAMIC;

	    			Body body = myWorld.world.createBody(bd);
	    			FixtureDef fd = new FixtureDef();
	    			CircleShape cd = new CircleShape();
	    			cd.m_radius = bodyRadius;
	    			fd.shape = cd;
	    			fd.density = 1.0f;
	    			//fd.filter.groupIndex = -2;
	    			body.createFixture(fd);

	    			//PeaPhy peaPhy1 = new PeaPhy(myWorld, myWorld.world, physUnitPerScreenUnit * event.x(), physUnitPerScreenUnit * event.y(), 0);

	    			cvjd.addBody(body);
	    			//cvjd.addBody(peaPhy1.getBody());
	    		}
	    		setMessageBox("joints loop ok...x, y = (" + cx + "," + cy + ")");

	    		cvjd.frequencyHz = 10.0f;
	    		cvjd.dampingRatio = 1.0f;
	    		myWorld.world.createJoint(cvjd);
	    		
	    		BodyDef bd2 = new BodyDef();
	    		bd2.fixedRotation = true;
    			bd2.position.set(new Vec2(cx, cy));
    			bd2.type = BodyType.DYNAMIC;
	    		Body body = myWorld.world.createBody(bd2);
    			FixtureDef fd = new FixtureDef();
    			CircleShape cd = new CircleShape();
    			cd.m_radius = bodyRadius;
    			fd.shape = cd;
    			fd.density = 1.0f;
    			//fd.filter.groupIndex = -2;
    			body.createFixture(fd);
    			Vec2 anchor = new Vec2(cx, 15.0f);
    			jd.initialize(ground, body, anchor);
    			myWorld.world.createJoint(jd);
    			
    			PeaPhy peaPhy1 = new PeaPhy(myWorld, myWorld.world, cx, 17, 0);

    			Vec2 anchor2 = new Vec2(cx, 20.0f);
    			jd.initialize(body, peaPhy1.getBody(), anchor2);
    			myWorld.world.createJoint(jd);

    			*/
    			
	    		/*
	    		bd2.position.set(new Vec2(cx + rx, cy + ry));
	    		bd2.type = BodyType.DYNAMIC;
	    		Body fallingBox = myWorld.world.createBody(bd2);
	    		PolygonShape psd = new PolygonShape();
	    		psd.setAsBox(3.0f,1.5f,new Vec2(cx,cy+15.0f),0.0f);
	    		bd2.position = new Vec2(cx,cy+15.0f);
	    		fallingBox.createFixture(psd,1.0f);
	    		*/
	    		
	    		setMessageBox("joints fim...");
	    		
	    		//*************************************
	    	}
	    });
	}

	private double radiansToDegree(double radians) {
		double result = radians * 180 / Math.PI;
		return result;
	}

	private ImageLayer criaCaixaFundo() {
		int width = 300;
	    int height = 150;
	    CanvasImage bgImage = graphics().createImage(width, height);
	    Canvas canvas = bgImage.canvas();
	    canvas.setFillColor(0xff87ceeb);
	    //canvas.setStrokeWidth(1);
	    canvas.fillRect(0, 0, width, height);
	    ImageLayer bg = graphics().createImageLayer(bgImage);
	    //bg.setTranslation(1, 1);
	    return bg;
	}

	private CanvasImage criaImage(int width, int height) {
		CanvasImage bgImage = graphics().createImage(width, height);
		return bgImage;
	}

	private ImageLayer getTextBox(String texto) {
		int width = 100;
	    int height = 50;
	    CanvasImage bgI = graphics().createImage(width, height);
	    Canvas canv = bgI.canvas();
	    //canvas.setFillColor(Color.rgb(200, 200, 200));
	    //canvas.setFillColor(0xff87ceeb);
	    //Font f = graphics().createFont("Times", Style.BOLD, 24f);
	    //TextLayout t = graphics().layoutText("teste2", new TextFormat().withFont(f));
	    //canv.drawText(t, 0, 0);

	    //f = graphics().createFont("Arial", Style.BOLD_ITALIC, 8f);
	    //t = graphics().layoutText("teste2", new TextFormat().withFont(f));
	    canv.drawText(texto, 10, 10);

	    ImageLayer bgl = graphics().createImageLayer(bgI);
	    //bg.setTranslation(1, 1);
	    return bgl;
	}

	private ImageLayer getGrid() {
		int width = 600;
	    int height = 300;
	    CanvasImage bgI = graphics().createImage(width, height);
	    Canvas canv = bgI.canvas();
	    //canvas.setFillColor(Color.rgb(200, 200, 200));
	    //canvas.setFillColor(0xff87ceeb);
	    //Font f = graphics().createFont("Times", Style.BOLD, 24f);
	    //TextLayout t = graphics().layoutText("teste2", new TextFormat().withFont(f));
	    //canv.drawText(t, 0, 0);

	    //f = graphics().createFont("Arial", Style.BOLD_ITALIC, 8f);
	    //t = graphics().layoutText("teste2", new TextFormat().withFont(f));
	    for (int i = 0; i < 600; i+=30) {
	    	canv.drawLine(i, 0, i, 300);
	    }
    	for (int j = 0; j < 300; j+=30) {
    		canv.drawLine(0, j, 600, j);
    	}

	    ImageLayer bgl = graphics().createImageLayer(bgI);
	    //bg.setTranslation(1, 1);
	    return bgl;
	}

	public void drawPoint(int xDest, int yDest) {
		//lyBracoD[0].setTranslation(xDest - (lyBracoD[0].width() / 2), yDest - (lyBracoD[0].height() / 2));
	}

	public void drawPoint(CanvasImage canvasImg, int xDest, int yDest, int c) {
	    canvasImg.canvas().setFillColor(c);
	    //canvasImg.canvas().drawPoint(xDest, yDest);
	    canvasImg.canvas().drawLine(xDest, yDest, xDest+5, yDest+5);
	}

	public CanvasImage drawNewPoint(int xDest, int yDest, int c) {
		CanvasImage canvasImg = graphics().createImage(10, 10);
	    canvasImg.canvas().setFillColor(c);
	    //canvasImg.canvas().drawPoint(xDest, yDest);
	    canvasImg.canvas().drawLine(xDest, yDest, xDest+5, yDest+5);
	    return canvasImg;
	}

	public CanvasImage drawNumber(int xDest, int yDest, int c, int number) {
		CanvasImage canvasImg = graphics().createImage(100, 100);
	    //canvasImg.canvas().setFillColor(c);
	    //canvasImg.canvas().drawPoint(xDest, yDest);
	    canvasImg.canvas().drawText(String.valueOf(number), xDest, yDest);
	    //canvasImg.canvas().drawLine(xDest, yDest, xDest+5, yDest+5);
	    return canvasImg;
	}

	public void drawBezierCurve(ImageLayer[] imgL, int xOrigem, int yOrigem, int xDest, int yDest, int bezierX, int bezierY) {

		int i = 0;
		for(double t=0.0; i < 11;t+=0.1, i++) {  
		    int x = (int) (  (1-t)*(1-t)*xOrigem + 2*(1-t)*t*bezierX+t*t*xDest);  
		    int y = (int) (  (1-t)*(1-t)*yOrigem + 2*(1-t)*t*bezierY+t*t*yDest);  

		    //plot something @  x,y coordinate here...
		    //canv.canvas().drawLine(x, y, x + 1, y + 1);
		    float xtmp = x - (imgL[i].width() / 2);
		    float ytmp = y - (imgL[i].height() / 2);

		    //System.out.println(i + " - " + t + " - (x0, y0) = (" + x + ", " + y + ")");
		    //System.out.println(i + " - " + t + " - (xtmp, ytmp) = (" + xtmp + ", " + ytmp + ")");

		    imgL[i].setTranslation(xtmp , ytmp);
		    //canv.canvas().drawImage(img, x, y);
		} 
	}

	@Override
	public void paint(float alpha) {
		// the background automatically paints itself, so no need to do anything here!
		myWorld.paint(alpha);
	}

	@Override
	public void update(float delta) {
		for (Pea pea : peas) {
			pea.update(delta);
		}
		myWorld.update(delta);

		/*
		Vec2 v = body.getLocalPoint(new Vec2(0,0));
		if (numMsg < 1000) {
			setMessageBox("body (x, y) = (" + v.x + "," + v.y + ")");
			numMsg++;
		}
		*/
	}

	@Override
	public int updateRate() {
		return 25;
	}

	public void rotationa(final ImageLayer lyImg, final float angulo, final float scaleX, final float scaleY) {

		class Contador {
			public float cont = 0;		
		};

		final Contador cont = new Contador();
		cont.cont = 0;
		final Timer t = new Timer() {

			@Override
			public void run() {
				if (cont.cont <= 1) {
					lyImg.setRotation(cont.cont * angulo);
					cont.cont += 0.1;
					System.out.println("cont=" + cont.cont + ", angulo=" + radiansToDegree(cont.cont * angulo));
				} else {
					lyImg.setScale(scaleX, scaleY);
					this.cancel();
				}
					
			}
		};
		t.scheduleRepeating(100);
	}

	public void posiciona(final ImageLayer lyImg, final int posXIni, final int posYIni, final double angulo, final double hip) {
		
		class Contador {
			public float cont = 0;		
		};
		System.out.println("(posXIni, posYIni) = (" + posXIni + ", " + posYIni + "), angulo = " + angulo + ", hip = " + hip);
		final double xlinha = (Math.cos(angulo) * hip);
		final double ylinha = (Math.sin(angulo) * hip); 
		System.out.println("(xlinha, ylinha) = (" + xlinha + ", " + ylinha + ")");
		final Contador cont = new Contador();
		cont.cont = 0;
		final Timer t = new Timer() {

			@Override
			public void run() {
				if (cont.cont <= 1.01) {
					int px = (int)((posXIni * cont.cont) + xlinha);
					int py = (int)((posYIni * cont.cont) + ylinha);
					System.out.println("cont=" + cont.cont + ", (px, py) = (" + px + ", " + py + "), angulo=" + radiansToDegree(cont.cont * angulo));
					lyImg.setTranslation(px - (lyImg.width() / 2), py - (lyImg.height() / 2));
					cont.cont += 0.1;
					
				} else {
					this.cancel();
				}
					
			}
		};
		t.scheduleRepeating(100);
	}

	public void testePhysics() {
		
		int width = 600;
		int height = 200;

		Vec2 gravity = new Vec2(0.0f, 10.0f);
	    World world = new World(gravity, true);
	    world.setWarmStarting(true);
	    world.setAutoClearForces(true);

	    // create the ground
	    Body ground = world.createBody(new BodyDef());
	    PolygonShape groundShape = new PolygonShape();
	    groundShape.setAsEdge(new Vec2(0, height*physUnitPerScreenUnit), new Vec2(width*physUnitPerScreenUnit, height*physUnitPerScreenUnit));
	    ground.createFixture(groundShape, 0.0f);

	    // create the walls
	    Body wallLeft = world.createBody(new BodyDef());
	    PolygonShape wallLeftShape = new PolygonShape();
	    wallLeftShape.setAsEdge(new Vec2(0, 0), new Vec2(0, height));
	    wallLeft.createFixture(wallLeftShape, 0.0f);
	    Body wallRight = world.createBody(new BodyDef());
	    PolygonShape wallRightShape = new PolygonShape();
	    wallRightShape.setAsEdge(new Vec2(width, 0), new Vec2(width, height));
	    wallRight.createFixture(wallRightShape, 0.0f);

	    FixtureDef fixtureDef = new FixtureDef();
	    BodyDef bodyDef = new BodyDef();
	    bodyDef.type = BodyType.DYNAMIC;
	    bodyDef.position = new Vec2(0, 0);
	    body = world.createBody(bodyDef);

	    CircleShape circleShape = new CircleShape();
	    circleShape.m_radius = 3f;
	    fixtureDef.shape = circleShape;
	    fixtureDef.density = 1.4f;
	    fixtureDef.friction = 0.1f;
	    fixtureDef.restitution = 0.35f;
	    circleShape.m_p.set(0, 0);
	    body.createFixture(fixtureDef);
	    body.setLinearDamping(0.2f);
	    body.setTransform(new Vec2(10, 10), 0);
	    body.setLinearVelocity(new Vec2(1, 1));
	    body.applyTorque(1f);
	}
}